#include "JinyiRSUClient.h"
#include "KafkaClient.h"
#include "Utils.h"
#include "httplib.h"
#include "nlohmann/json.hpp"

void JinyiRsuClient::Init(std::shared_ptr<DeviceInfo> info) {
    _device_info = info;
    SPDLOG_INFO("金溢： {}:{}", _device_info->IP, _device_info->Port);
}

void JinyiRsuClient::Start() {
    _svr.Post("/evi", [this](const httplib::Request &req, httplib::Response &res) {
        auto doc = nlohmann::json::parse(req.body);
        SPDLOG_INFO(doc.dump(4));
        _rsuID = doc["rsuId"].get<std::string>();
        _devID = doc["devId"].get<std::string>();
        _vendor = doc["brand"].get<std::string>();
        _version = doc["sysInfo"]["version"].get<std::string>();

        auto address = req.remote_addr;
        if (!_rsu_mapping.contains(address)) {
            RsuInfo info;
            info.Address = address;
            info.DevID = _devID;
            info.RsuID = _rsuID;
            _rsu_mapping[address] = info;
        }

        {
            nlohmann::json info = {
                { "salt", "cdtye_2024" },
                { "taskId", GenerateUuidWithoutDelimiter() },
                { "rsuCtlIp", address },
                { "rsuCtlPort", "8080" },
                { "vendorName", _vendor },
                { "rsuNo", _rsuID },
                { "rsuCtlNo", _devID },
                { "dataTime", fmt::format("{:%Y-%m-%d %H:%M:%S}", fmt::localtime(std::time(nullptr))) },
                { "rsuStatus", 1 },
                { "plateNumber", doc["vehInfo"]["plateNumber"].get<std::string>() },
                { "plateColor", doc["vehInfo"]["plateColor"].get<int>() },
                { "vehicleType", doc["vehInfo"]["vehicleType"].get<int>() },
                { "userType", doc["vehInfo"]["userType"].get<int>() },
                { "weightTotal", doc["vehInfo"]["weightTotal"].get<int>() },
                { "weightCapacity", doc["vehInfo"]["weightCapacity"].get<int>() },
                { "specialFlag", doc["vehInfo"]["specialFlag"].get<int>() },
                { "lastGantryHex", doc["vehInfo"]["lastGantryHex"].get<std::string>() },
                { "lastGantryTime", doc["vehInfo"]["lastGantryTime"].get<std::string>() },
            };

            SPDLOG_INFO(info.dump(4));
            KafkaClient::GetInstance()->Publish(info.dump(4));
        }

        nlohmann::json response = { { "code", 0 }, { "data", { { "devId", _devID } } }, { "msg", "成功" } };

        auto text = response.dump(4);
        res.set_content(text, "application/json");
    });

    _svr.Post("/heartbeat", [this](const httplib::Request &req, httplib::Response &res) {
        auto doc = nlohmann::json::parse(req.body);
        SPDLOG_INFO(doc.dump(4));

        auto rsuId = doc["rsuId"].get<std::string>();
        auto timestamp = fmt::format("{:%Y-%m-%dT%H:%M:%S.000}", fmt::localtime(std::time(nullptr)));

        auto address = req.remote_addr;
        if (!_rsu_mapping.contains(address)) {
            return;
        }

        RsuInfo rsu_info = _rsu_mapping[address];
        nlohmann::json info
            = { { "salt", "cdtye_2024" },
                { "taskId", GenerateUuidWithoutDelimiter() },
                { "rsuCtlIp", rsu_info.Address },
                { "rsuCtlPort", "8080" },
                { "vendorName", _vendor },
                { "rsuNo", rsuId },
                { "rsuCtlNo", rsu_info.DevID },
                { "storage", 0.0 },
                { "dataTime", fmt::format("{:%Y-%m-%d %H:%M:%S}", fmt::localtime(std::time(nullptr))) },
                { "rsuStatus", 1 },
                { "ctlHardwareNo", " " },
                { "ctlSoftwareNo", _version },
                { "headHardwareNo", " " },
                { "headSoftwareNo", doc["programVer"].get<std::string>() },
                { "temperature", 0.0 },
                { "mbNetStatus", 1 },
                { "rsuHeadNum", 1 },
                { "psamNum", 0 },
                { "rsuHeadList",
                  { { "rsuHeadNo", rsuId },
                    { "commStatus", 1 },
                    { "rsuChannel", 1 },
                    { "launchStatus", 1 },
                    { "rcvStatus", 1 },
                    { "powerGrade", doc["txPower"].get<int>() } } } };

        SPDLOG_INFO(info.dump(4));
        KafkaClient::GetInstance()->Publish(info.dump(4));

        nlohmann::json response = { { "code", 0 },
                                    { "data", { { "rsuId", rsuId }, { "timestamp", timestamp } } },
                                    { "msg", "成功" } };
        auto text = response.dump(4);
        res.set_content(text, "application/json");
    });

    SPDLOG_INFO("创建HTTP服务端");
    _svr.listen("0.0.0.0", _device_info->Port);
}

void JinyiRsuClient::Stop() {
    _svr.stop();
}
